package urjc.as.emergencies.data;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Esta clase almacena todos los recursos por su URI
 * 
 * @author ahiges
 * 
 */
public class Storage {

	// ///////////////// ATRIBUTOS

	/**
	 * Patrón Singleton.
	 */
	private static Storage instance = null;
	/**
	 * Las entidades son almacenadas referenciándolas mediante su URI.
	 */
	private Map<String, BaseEntity> almacen;

	// ///////////////// CONSTRUCTORES

	/**
	 * Constructor por defecto.
	 */
	private Storage() {
		// Inicializamos el almacén como una tabla Hash concurrente.
		this.almacen = new ConcurrentHashMap<String, BaseEntity>();
	}

	// ///////////////// OTROS MÉTODOS

	/**
	 * Devuelve la instancia de almacenamiento.
	 */
	public static Storage getInstance() {
		if (instance == null) {
			instance = new Storage();
			return instance;
		} else {
			return instance;
		}
	}

	/**
	 * Añade una entidad al almacén. Se utiliza la URI como clave en el
	 * almacenamiento.
	 */
	public void addEntity(BaseEntity entidad) {
		// Almacenamos la entidad, localizándola mediante su URI
		if (entidad.getUri() != null)
			this.almacen.put(entidad.getUri(), entidad);
		else
			// Si la entidad a almacenar no tiene una URI definida, no puede
			// almacenarse.
			throw new NullPointerException();
	}

	/**
	 * Devuelve la entidad cuya localización coincide con la URI determinada. Si
	 * la entidad no se encuentra en el almacén, se devuelve null.
	 * 
	 * @param uri
	 *            URI de una entidad existente en el almacen.
	 * @return La entidad solicitada o null, si no existe ninguna entidad
	 *         identificada con esa URI.
	 */
	public BaseEntity getEntity(String uri) {
		return this.almacen.get(uri);
	}

	/**
	 * Elimina la entidad identificada con dicha URI del almacén. Devuelve dicha
	 * entidad o null si no existía ninguna entidad identificada con dicha URI.
	 * 
	 * @return La entidad eliminada o null si no existía ninguna entidad
	 *         identificada con dicha URI.
	 */
	public BaseEntity delEntity(String uri) {
		return this.almacen.remove(uri);
	}

}
